﻿using System.Net;
using System.Runtime.Serialization;

namespace Toybox.NicoSharp.Video.MyPage
{
	using Abstracts;

	public class Deflist : MyPagePrimitives.AbstractMyPageList
	{

		#region Constructor

		public Deflist(CookieCollection cookies = null)
			: base(cookies)
		{
			this.Token = new Token(NicoUrls.VideoTop + "my/mylist");
			this.Token.Type = TokenType.NicoAPI;
		}

		#endregion Constructor


		#region Public Methods

		public ListResult List()
		{
			return this.Get<ListResult>(this.GetUrl("list"));
		}

		public AddResult Add(Item item)
		{
			return this.MethodAU<AddResult>("add", item);
		}

		public UpdateResult Update(Item item)
		{
			return this.MethodAU<UpdateResult>("update", item);
		}

		public DelResult Delete(Item item)
		{
			return this.Delete(new Item[] { item });
		}

		public DelResult Delete(Item[] items)
		{
			return this.MethodD<DelResult>("delete", items);
		}

		public MoveResult Move(string target_group_id, Item item)
		{
			return this.Move(target_group_id, new Item[] { item });
		}

		public MoveResult Move(string target_group_id, Item[] items)
		{
			return this.MethodMC<MoveResult>("move", target_group_id, items);
		}

		public CopyResult Copy(string target_group_id, Item item)
		{
			return this.Copy(target_group_id, new Item[] { item });
		}

		public CopyResult Copy(string target_group_id, Item[] items)
		{
			return this.MethodMC<CopyResult>("copy", target_group_id, items);
		}

		#endregion Public Methods

		#region Protected Methods

		protected override string GetUrl(string method)
		{
			return NicoUrls.FlApi + "deflist/" + method;
		}

		/// <summary>
		/// Add, Updateで使用
		/// </summary>
		/// <param name="group_id"></param>
		/// <param name="method"></param>
		/// <param name="item"></param>
		/// <returns></returns>
		protected virtual T MethodAU<T>(string method, Item item)
		{
			if (this.Token.Expired) this.Token.Update();

			string url = GetUrl(method) + "?" + item.ToString() + "&token=" + this.Token.Value;
			return this.Get<T>(url);
		}

		/// <summary>
		/// Deleteで使用
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="method"></param>
		/// <param name="items"></param>
		/// <returns></returns>
		protected virtual T MethodD<T>(string method, Item[] items)
		{
			if (this.Token.Expired) this.Token.Update();

			string url = this.GetUrl(method) + "?";
			foreach (Item item in items)
				url += item.ToStringForList() + "&";

			url += "token=" + this.Token.Value;

			return this.Get<T>(url);
		}

		/// <summary>
		/// Move, Copyで使用
		/// </summary>
		/// <param name="group_id"></param>
		/// <param name="method"></param>
		/// <param name="target_group_id"></param>
		/// <param name="items"></param>
		/// <returns></returns>
		protected virtual T MethodMC<T>(string method, string target_group_id, Item[] items)
		{
			if (this.Token.Expired) this.Token.Update();

			string url = GetUrl(method) + "?target_group_id=" + target_group_id;
			foreach (Item item in items)
				url += "&" + item.ToStringForList();

			url += "&token=" + this.Token.Value;

			return this.Get<T>(url);
		}

		#endregion Protected Methods


		#region [SubClass]

		[DataContract]
		public class ListResult : Mylist.ListResult
		{
		}

		[DataContract]
		public class AddResult : Mylist.AddResult
		{
		}

		[DataContract]
		public class UpdateResult : Mylist.UpdateResult
		{
		}

		[DataContract]
		public class DelResult : Mylist.DelResult
		{
		}

		[DataContract]
		public class MoveResult : Mylist.MoveResult
		{
		}

		[DataContract]
		public class CopyResult : MoveResult
		{
		}

		#endregion [SubClass]

	}
}